#include <iostream>
#include <semaphore.h>
#include <vector>
#include <pthread.h>
using namespace std;
const static int DefaultNUM = 5;
template <class T>
class cp_queue
{
private:
    sem_t cDate_;
    sem_t pCap_;

    int p_step;
    int c_step; // 定义队列下标

    int maxCap_;

    pthread_mutex_t C_mutex;
    pthread_mutex_t P_mutex;

    vector<T> ringqueue;

public:
    void p(sem_t &sem)
    {
        sem_wait(&sem);
    }
    void v(sem_t &sem)
    {
        sem_post(&sem);
    }
    void Lock(pthread_mutex_t &mutex)
    {
        pthread_mutex_lock(&mutex);
    }
    void Unlock(pthread_mutex_t &mutex)
    {
        pthread_mutex_unlock(&mutex);
    }
    cp_queue(int maxcap = DefaultNUM) : maxCap_(maxcap), p_step(0), c_step(0), ringqueue(maxcap)
    {
        pthread_mutex_init(&C_mutex, NULL);
        pthread_mutex_init(&P_mutex, NULL);
        sem_init(&cDate_, 0, 0);
        sem_init(&pCap_, 0, maxCap_);
    };

    void push(const T &in)
    {
        p(pCap_);
        Lock(P_mutex);
        ringqueue[p_step] = in;
        p_step++;
        p_step %= maxCap_;
        Unlock(P_mutex);
        v(cDate_);
    }
    void pop(T *out)
    {
        p(cDate_);
        Lock(C_mutex);
        *out = ringqueue[c_step];

        // 维持环形特性
        c_step++;
        c_step %= maxCap_;

        Unlock(C_mutex);

        v(pCap_);
    }
    ~cp_queue()
    {
        pthread_mutex_destroy(&C_mutex);
        pthread_mutex_destroy(&P_mutex);
        sem_destroy(&cDate_);
        sem_destroy(&pCap_);
    };
};
